package com.yuanchu.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.GoodsFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.order.client.FeignMediaClient;
import com.yuanchu.order.client.FeignStoreClient;
import com.yuanchu.order.dao.YoshopCommentDao;
import com.yuanchu.order.dao.YoshopCommentImageDao;
import com.yuanchu.order.dto.CommentImageDto;
import com.yuanchu.order.dto.EditOrderCommentDto;
import com.yuanchu.order.dto.OrderCommentParamsDto;
import com.yuanchu.order.dto.QueryCommentParamsDto;
import com.yuanchu.order.entity.*;
import com.yuanchu.order.service.YoshopCommentService;
import com.yuanchu.order.service.YoshopOrderGoodsService;
import com.yuanchu.order.service.YoshopOrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;


@Service("yoshopCommentService")
public class YoshopCommentServiceImpl extends ServiceImpl<YoshopCommentDao, YoshopCommentEntity> implements YoshopCommentService {

    @Resource
    private YoshopOrderService orderService;
    @Resource
    private YoshopCommentImageDao commentImageDao;
    @Resource
    private YoshopOrderGoodsService orderGoodsService;
    @Resource
    private FeignStoreClient feignStoreClient;
    @Resource
    private FeignMediaClient feignMediaClient;
    @Override
    public List<YoshopOrderGoodsEntity> queryOrderComment(Integer orderId, Integer userId) {
        return orderService.queryOrderGoods(orderId, userId);
    }

    @Override
    @Transactional
    public boolean submitOrderComment(OrderCommentParamsDto params, Integer userId) {
        int flag = 0;
        for (OrderCommentParamsDto.OrderCommentForm commentForm : params.getForm()) {
            LambdaQueryWrapper<YoshopCommentEntity> lqw = new LambdaQueryWrapper<>();
            lqw.eq(YoshopCommentEntity::getOrderId, params.getOrderId())
                    .eq(YoshopCommentEntity::getUserId, userId)
                    .eq(YoshopCommentEntity::getOrderGoodsId, commentForm.getOrderGoodsId())
                    .eq(YoshopCommentEntity::getStoreId, 10001);
            int commentNum = this.count(lqw);
            if (commentNum > 0){
                // 订单已评价
                continue;
            }
            YoshopCommentEntity comment = new YoshopCommentEntity();
            comment.setScore(commentForm.getScore());
            comment.setContent(commentForm.getContent());
            comment.setUserId(userId);
            comment.setGoodsId(commentForm.getGoodsId());
            comment.setStoreId(10001);
            comment.setOrderId(Integer.valueOf(params.getOrderId()));
            comment.setOrderGoodsId(commentForm.getOrderGoodsId());
            comment.setCreateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            comment.setUpdateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            if (!CollectionUtils.isEmpty(commentForm.getImageList())){
                comment.setIsPicture(1);
            }
            // 1、保存订单评价
            boolean saveComment = this.save(comment);
            if (!saveComment){
                throw new YuanChuException("保存订单评价失败");
            }
            // 2、保存订单评价图片
            List<Integer> fileIds = commentForm.getUploaded();
            if (!CollectionUtils.isEmpty(fileIds)) {
                for (Integer fileId : fileIds) {
                    YoshopCommentImageEntity commentImage = new YoshopCommentImageEntity();
                    commentImage.setCommentId(comment.getCommentId());
                    commentImage.setStoreId(10001);
                    commentImage.setImageId(fileId);
                    commentImage.setCreateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
                    int insert = commentImageDao.insert(commentImage);
                    if (insert < 1){
                        throw new YuanChuException("保存订单评价图片失败");
                    }
                }
            }
            // 3、更新订单状态
            UpdateWrapper<YoshopOrderEntity> updateWrapper = new UpdateWrapper<YoshopOrderEntity>().eq("order_id", params.getOrderId())
                    .eq("user_id", userId)
                    .eq("store_id", comment.getStoreId())
                    .set("is_comment", 1);
            boolean updateOrderStatus = orderService.update(updateWrapper);
            if (!updateOrderStatus){
                throw new YuanChuException("更新订单状态失败");
            }

            // 4、更新订单商品状态
            UpdateWrapper<YoshopOrderGoodsEntity> updateOrderGoodsWrapper = new UpdateWrapper<YoshopOrderGoodsEntity>()
                    .eq("order_goods_id", commentForm.getOrderGoodsId())
                    .eq("user_id", userId)
                    .eq("store_id", comment.getStoreId())
                    .set("is_comment", 1);
            boolean update = orderGoodsService.update(updateOrderGoodsWrapper);
            if (!update){
                throw new YuanChuException("更新订单商品状态失败");
            }
            flag++;

        }
        return flag > 0;

    }

    @Override
    public PageResult<CommentImageDto> queryGoodsComment(QueryCommentParamsDto params, int storeId) {
        LambdaQueryWrapper<YoshopCommentEntity> lqw = new LambdaQueryWrapper<>();
        // 根据订单编号查询
        lqw.eq(params.getOrderId() != null, YoshopCommentEntity::getOrderId, params.getOrderId());
        // 根据用户id查询
        lqw.eq(params.getUserId() != null, YoshopCommentEntity::getUserId, params.getUserId());
        // 根据状态查询
        if (params.getStatus() != null && params.getStatus() > 0 ){
            lqw.eq(YoshopCommentEntity::getStatus, params.getStatus());
        }
        // 根据商品评价查询
        lqw.eq(params.getScore() != null, YoshopCommentEntity::getScore, params.getScore());
        lqw.orderByAsc(YoshopCommentEntity::getSort);
        Page<YoshopCommentEntity> page = this.page(new Page<>(params.getPage(), params.getLimit()));
        List<YoshopCommentEntity> records = page.getRecords();
        List<CommentImageDto> comments = new ArrayList<>();
        records.forEach(comment ->{
            CommentImageDto commentImageDto = new CommentImageDto();
            BeanUtils.copyProperties(comment, commentImageDto);
            commentImageDto.setOrderGoods(getOrderGoods(comment.getOrderGoodsId()));
            commentImageDto.setUser(getCommentUser(comment.getUserId()));
            commentImageDto.setCreateTime(DateFormatUtils.formatDatetime(comment.getCreateTime()));
            comments.add(commentImageDto);
        });
        return PageResult.formatPageResult(comments, params.getPage(), params.getLimit(), page.getTotal());

    }

    @Transactional
    @Override
    public void editOrderComment(EditOrderCommentDto params, int storeId) {
        Integer commentId = params.getCommentId();
        YoshopCommentEntity comment = this.getById(commentId);
        EditOrderCommentDto.CommentForm commentForm = params.getForm();
        comment.setScore(commentForm.getScore());
        comment.setContent(commentForm.getContent());
        comment.setStatus(commentForm.getStatus());
        comment.setSort(commentForm.getSort());
        comment.setUpdateTime(String.valueOf(Instant.now().toEpochMilli()/1000));
        this.updateById(comment);
        if (CollectionUtils.isEmpty(commentForm.getImageIds())){
            return;
        }
        List<Integer> imageIds = commentForm.getImageIds();
        List<YoshopCommentImageEntity> commentImageEntities = commentImageDao.selectList(new QueryWrapper<YoshopCommentImageEntity>().eq("comment_id", commentId)
                .eq("store_id", storeId));
        List<Integer> oldImageIds = commentImageEntities.stream().map(YoshopCommentImageEntity::getImageId).collect(Collectors.toList());
        oldImageIds.forEach(imageId -> {
            if (!imageIds.contains(imageId)){
                commentImageDao.deleteById(imageId);
            }else {
                imageIds.remove(imageId);
            }
        });
        imageIds.forEach(imageId -> {
            YoshopCommentImageEntity commentImage = new YoshopCommentImageEntity();
            commentImage.setCommentId(commentId);
            commentImage.setImageId(imageId);
            commentImage.setStoreId(storeId);
            commentImage.setCreateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            commentImageDao.insert(commentImage);
        });

    }

    @Override
    @Transactional
    public void deleteOrderComment(EditOrderCommentDto params, int storeId) {
        Integer commentId = params.getCommentId();
        this.update(new UpdateWrapper<YoshopCommentEntity>().eq("comment_id", commentId)
                .eq("store_id", storeId)
                .set("is_delete", 1));
        // 删除评价图片
        // commentImageDao.delete(new QueryWrapper<YoshopCommentImageEntity>().eq("comment_id", commentId)
        //         .eq("store_id", storeId));
    }

    @Override
    public CommentImageDto queryGoodsCommentDetail(Integer commentId, int storeId) {
        YoshopCommentEntity commentEntity = this.getOne(new QueryWrapper<YoshopCommentEntity>().eq("comment_id", commentId)
                .eq("store_id", storeId));
        if (commentEntity == null){
            return null;
        }
        CommentImageDto commentImageDto = new CommentImageDto();
        BeanUtils.copyProperties(commentEntity, commentImageDto);
        List<YoshopCommentImageEntity> commentImageEntities = commentImageDao.selectList(new QueryWrapper<YoshopCommentImageEntity>().eq("comment_id", commentId));
        List<Integer> imageIds = commentImageEntities.stream().map(YoshopCommentImageEntity::getImageId).collect(Collectors.toList());
        commentImageDto.setImageIds(imageIds);
        List<YoshopUploadFileEntity> files = feignMediaClient.getUploadFileByIds(imageIds);
        commentImageDto.setImageList(files);
        commentImageDto.setImages(commentImageEntities);
        commentImageDto.setCreateTime(DateFormatUtils.formatDatetime(commentEntity.getCreateTime()));
        return commentImageDto;

    }


    private CommentImageDto.CommentUser getCommentUser(Integer userId) {
        YoshopUserEntity user = feignStoreClient.queryUserByUserId(userId);
        if (user != null){
            CommentImageDto.CommentUser commentUser = new CommentImageDto.CommentUser();
            BeanUtils.copyProperties(user, commentUser);
            commentUser.setAvatarUrl(user.getAvatarUrl());
            return commentUser;
        }
        return null;
    }

    private CommentImageDto.OrderGoods getOrderGoods(Integer orderGoodsId) {
        YoshopOrderGoodsEntity orderGoodsEntity = orderGoodsService.getOne(new QueryWrapper<YoshopOrderGoodsEntity>()
                .eq("order_goods_id", orderGoodsId));
        if (orderGoodsEntity == null){
            return null;
        }
        setGoodsProps(orderGoodsEntity);
        CommentImageDto.OrderGoods orderGoods = new CommentImageDto.OrderGoods();
        BeanUtils.copyProperties(orderGoodsEntity, orderGoods);
        YoshopUploadFileEntity file = feignMediaClient.getUploadFileById(orderGoods.getImageId());
        orderGoods.setGoodsImage(file.getPreviewUrl());
        return orderGoods;
    }


    private void setGoodsProps(YoshopOrderGoodsEntity orderGoods) {
        Object goodsProps = orderGoods.getGoodsProps();
        if (goodsProps != null) {
            List<Map<String, Object>> props = GoodsFormatUtils.formatGoodsProps(goodsProps.toString());
            orderGoods.setGoodsProps(props);
        }
        YoshopUploadFileEntity file = feignMediaClient.getUploadFileById(orderGoods.getImageId());
        orderGoods.setGoodsImage(file.getPreviewUrl());
    }

}